home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / amiga / hdf / hdf.lha / DFR8.C < prev    next >
Encoding:
C/C++ Source or Header  |  1980-02-06  |  30.2 KB  |  874 lines

  1. /*****************************************************************************
  2. *              NCSA HDF version 3.10r3
  3. *                Dec 6, 1990
  4. *
  5. * NCSA HDF Version 3.10r3 source code and documentation are in the public
  6. * domain.  Specifically, we give to the public domain all rights for future
  7. * licensing of the source code, all resale rights, and all publishing rights.
  8. * We ask, but do not require, that the following message be included in all
  9. * derived works:
  10. * Portions developed at the National Center for Supercomputing Applications at
  11. * the University of Illinois at Urbana-Champaign.
  12. * THE UNIVERSITY OF ILLINOIS GIVES NO WARRANTY, EXPRESSED OR IMPLIED, FOR THE
  13. * SOFTWARE AND/OR DOCUMENTATION PROVIDED, INCLUDING, WITHOUT LIMITATION,
  14. * WARRANTY OF MERCHANTABILITY AND WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE
  15. *****************************************************************************/
  16.  
  17. #ifdef RCSID
  18. static char RcsId[] = "@(#)$Revision: 3.4 $";
  19. #endif
  20. /*
  21. $Header: /pita/work/HDF/dev/RCS/src/dfr8.c,v 3.4 90/07/02 10:12:00 clow beta $
  22.  
  23. $Log:    dfr8.c,v $
  24.  * Revision 3.4  90/07/02  10:12:00  clow
  25.  * some cosmetic modifications
  26.  * 
  27. */
  28. /*-----------------------------------------------------------------------------
  29.  * File:    dfr8.c
  30.  * Purpose: read and write 8-bit Raster Image Groups
  31.  * Invokes: df.c, dfcomp.c, dfgroup.c, dfrig.h
  32.  * Contents: 
  33.  *  DFR8getdims: retrieve information about 8-bit image dimensions
  34.  *  DFR8getimage: retrieve 8-bit image and associated palette
  35.  *  DFR8setpalette: specify palette to be used with subsequent 8-bit images
  36.  *  DFR8Iputimage: internal routine that write 8-bit images to files
  37.  *  DFR8putimage: write 8-bit image into an HDF file
  38.  *  DFR8addimage: append another 8-bit image to an HDF file
  39.  *  DFR8getrig: read in a raster image group for 8-bit images
  40.  *  DFR8putrig: write out a raster image group for 8-bit images
  41.  *  DFR8nimages: number of images in HDF file
  42.  *  DFR8readref: get image with this reference number next
  43.  *  DFR8writeref: put image with this reference number next
  44.  *  DFR8restart: forget info about last file accessed - restart from beginning
  45.  *  DFR8lastref: return reference number of last element read or written
  46.  *  DFR8Iopen: open/reopen file
  47.  *  DFR8Iriginfo: obtain info about next RIG/RI8 to get
  48.  * Remarks: A RIG specifies attributes associated with an image - palette, 
  49.  *          dimension, compression, color compensation etc.
  50.  *          The palette for an 8-bit image is assumed to always be 768 bytes
  51.  *          The palette is arranged as RGBRGB...
  52.  *---------------------------------------------------------------------------*/
  53.  
  54.  
  55. #include "df.h"
  56.  
  57. static int foundRig = -1;    /* -1: don't know if HDF file has RIGs */
  58.                 /* 0: No RIGs, try for RI8s etc. */
  59.                 /* 1: RIGs used, ignore RI8s etc. */
  60. static DFRrig Readrig;        /* information about RIG being read */
  61. static DFRrig Writerig;        /* information about RIG being written */
  62. static int Newdata = 0;        /* does Readrig contain fresh data? */
  63. static uint16 Writeref=0;    /* ref of next image to put in this file */
  64. static int Newpalette=(-1);    /* -1 = no palette is associated */
  65.                 /* 0 = palette already written out */
  66.                 /* 1 = new palette, not yet written out */
  67. static char Palette[768];    /* to store palette for 8-bit images */
  68. static uint16 Refset=0;        /* Ref of image to get next */
  69. static uint16 Lastref = 0;    /* Last ref read/written */
  70. static DFRrig Zrig = {        /* empty RIG for initialization */
  71.     {0, 0}, {0, 0, 0, 0, 0, 0, 0, 0},
  72.     {0, 0}, {0, 0, 0, 0, 0, 0, 0, 0},
  73.     {0, 0}, {0, 0, 0, 0, 0, 0, 0, 0},
  74.     0, 0, 0.0, 0.0, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0},
  75.     {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, NULL
  76. };
  77.  
  78. #ifndef VMS
  79. DF *DFR8Iopen();
  80. #else /*VMS*/
  81. DF *_DFR8Iopen();
  82. #endif
  83.  
  84. typedef struct R8dim {
  85.     uint16 xd;
  86.     uint16 yd;
  87. } R8dim;            /* dimensions of raster-8 image */
  88.  
  89.  
  90. /*-----------------------------------------------------------------------------
  91.  * Name:    DFR8getdims
  92.  * Purpose: get dimensions of next image from RIG, also if there is a palette
  93.  * Inputs:  filename: name of HDF file
  94.  *          pxdim, pxdim, pointer to locations for returning x,y dimensions
  95.  *          pispal: pointer to location for rtning whether there is a palette
  96.  * Returns: 0 on success, -1 on failure with DFerror set
  97.  *          *pxdim, *pydim are set to dimensions of the next image
  98.  *          *pispal is set to 1 if a palette is associated with it, else 0
  99.  * Users:   HDF HLL (high-level library) users, utilities, other routines
  100.  * Invokes: DFR8Iopen, DFclose, DFR8Iriginfo, DFIerr
  101.  * Remarks: will also handle file with just raster-8 tags: RI8, CI8, ID8, IP8
  102.  *---------------------------------------------------------------------------*/
  103.  
  104. int DFR8getdims(filename, pxdim, pydim, pispal)
  105. char *filename;
  106. int32 *pxdim, *pydim;
  107. int *pispal;
  108. {
  109.     DF *dfile;
  110.  
  111.     DFerror = DFE_NOERROR;
  112.  
  113.     if (!pxdim || !pydim) {    /* check for zero dimensions */
  114.         DFerror = DFE_BADPTR;
  115.         return(-1);
  116.     }
  117.  
  118.     dfile = DFR8Iopen(filename, DFACC_READ);
  119.     if (dfile == NULL) return(-1);
  120.  
  121.     if (DFR8Iriginfo(dfile)<0)    /* reads next RIG or RI8 from file */
  122.         return(DFIerr(dfile));    /* on error, close file and return -1 */
  123.  
  124.     Newdata = 1;
  125.     *pxdim = Readrig.descimage.xdim;
  126.     *pydim = Readrig.descimage.ydim;
  127.     if (pispal) *pispal = Readrig.lut.tag ? 1 : 0; /* is there a palette */
  128.  
  129.     return(DFclose(dfile));
  130. }
  131.  
  132. /*-----------------------------------------------------------------------------
  133.  * Name:    DFR8getimage
  134.  * Purpose: get next image from a RIG, get palette also if desired
  135.  * Inputs:  filename: name of HDF file
  136.  *          image: space to read image into
  137.  *          xdim, ydim: dimensions of space allocated by user for image
  138.  *          pal: 768-byte space for palette, null if palette not wanted
  139.  * Returns: 0 on success, -1 on failure with DFerror set
  140.  *          image in image, palette in pal
  141.  * Users:   HDF HLL users, utilities, other routines
  142.  * Invokes: DFR8Iopen, DFR8Iriginfo, DFIerr, DFclose, DFgetelement, DFgetcomp
  143.  * Remarks: Will also get RI8s and CI8s if no RIGs in file
  144.  *          Normally,DFR8getdims is called first and it finds next image to get
  145.  *          But if that is not called, DFR8getimage will itself find next image
  146.  *          Automatically decompresses images
  147.  *---------------------------------------------------------------------------*/
  148.  
  149. int DFR8getimage(filename, image, xdim, ydim, pal)
  150. char *filename;
  151. int32 xdim, ydim;
  152. char *image;
  153. char *pal;
  154. {
  155.     DF *dfile;
  156.  
  157.     DFerror = DFE_NOERROR;
  158.  
  159.     if ((xdim<=0) || (ydim<=0)) {
  160.         DFerror = DFE_BADDIM;
  161.         return(-1);
  162.     }
  163.  
  164.     dfile = DFR8Iopen(filename, DFACC_READ);
  165.     if (dfile == NULL) return(-1);
  166.  
  167.     if (!Newdata) {        /* if Readrig not fresh */
  168.         if (DFR8Iriginfo(dfile)<0) /* reads next RIG or RI8 from file */
  169.             return(DFIerr(dfile)); /* on error, close file and return -1 */
  170.     }
  171.     Newdata = 0;        /* read new RIG next time */
  172.  
  173.     if ((Readrig.descimage.xdim > xdim) || (Readrig.descimage.ydim > ydim)) {
  174.         DFerror = DFE_NOTENOUGH; /* not enough space */
  175.         return(DFIerr(dfile));
  176.     }
  177.  
  178.     /* read image */
  179.     if (Readrig.descimage.compr.tag) { /* compressed image */
  180.         if (DFgetcomp(dfile, Readrig.image.tag, Readrig.image.ref, image,
  181.               Readrig.descimage.xdim, Readrig.descimage.ydim,
  182.               Readrig.descimage.compr.tag)<0)
  183.             return(DFIerr(dfile));
  184.     } else {            /* non-compressed raster image */
  185.         if (DFgetelement(dfile, Readrig.image.tag, Readrig.image.ref, image)<0)
  186.             return(DFIerr(dfile));
  187.     }
  188.     if (xdim > Readrig.descimage.xdim) {
  189.     int off1, off2;
  190.     int x, y;
  191.     off1 = (Readrig.descimage.ydim - 1) * xdim;
  192.     off2 = (Readrig.descimage.ydim - 1) * Readrig.descimage.xdim;
  193.     for (y = Readrig.descimage.ydim - 1; y > 0; y-- ) {
  194.         for (x = Readrig.descimage.xdim - 1; x >= 0; x--)
  195.         image[off1+x] = image[off2+x];
  196.         off1 -= xdim;
  197.         off2 -= Readrig.descimage.xdim;
  198.     }
  199.     }
  200.  
  201.     if (pal && Readrig.lut.tag) { /* read palette */
  202.         if (DFgetelement(dfile, Readrig.lut.tag, Readrig.lut.ref, pal)<0)
  203.             return(DFIerr(dfile));
  204.     }
  205.     return(DFclose(dfile));
  206. }
  207.  
  208. /*-----------------------------------------------------------------------------
  209.  * Name:    DFR8setpalette
  210.  * Purpose: set palette for subsequent images
  211.  * Inputs:  pal: palette to set
  212.  * Returns: 0 on success, -1 on failure with DFerror set
  213.  * Users:   HDF users, utilities, other routines
  214.  * Invokes: none
  215.  * Remarks: if pal is NULL, no palette is associated with subsequent images
  216.  *---------------------------------------------------------------------------*/
  217.  
  218. int DFR8setpalette(pal)
  219. char *pal;
  220. {
  221.     int i;
  222.  
  223.     DFerror = DFE_NOERROR;
  224.  
  225.     if (!pal) {
  226.         Newpalette = -1;    /* no palette */
  227.         Writerig.lut.tag = 0;
  228.         Writerig.lut.ref = 0;   /* forget tag/ref of previous palette */
  229.         Writerig.desclut.xdim = 0;
  230.         Writerig.desclut.ncomponents = 0;
  231.     } else {            /* store palette */
  232.         for (i=0; i<768; i++)
  233.             Palette[i] = pal[i];
  234.         Newpalette = 1;
  235.     }
  236.     return(0);
  237. }
  238.  
  239. /*-----------------------------------------------------------------------------
  240.  * Name:    DFR8Iputimage
  241.  * Purpose: Internal routine to write RIG to file
  242.  * Inputs:  filename: name of HDF file
  243.  *          image: image to be written to file
  244.  *          xdim, ydim: dimensions of image
  245.  *          compress: compression scheme to be used on image, 0 if none
  246.  *                    possible values are DFTAG_RLE and DFTAG_IMC
  247.  *          op: 0 will overwrite existing file, 1 will append image to file
  248.  * Returns: 0 on success, -1 on failure with DFerror set
  249.  * Users:   HDF systems programmers, DFR8putimage, DFR8addimage
  250.  * Invokes: DFR8Iopen, DFclose, DFputelement, DFdup, DFR8putrig, DFputcomp,
  251.  *          DFIerr
  252.  * Remarks: Palette will be associated with image is isPalette is 1
  253.  *          Palette will be written to file if not written before (Palref=0)
  254.  *          Creates both RIG and RI8/CI8 tags, to accomodate older programs
  255.  *---------------------------------------------------------------------------*/
  256.  
  257. int DFR8Iputimage(filename, image, xdim, ydim, compress, op)
  258. char *filename;
  259. int32 xdim, ydim;
  260. char *image;
  261. int compress;               /* compression scheme */
  262. int op;                     /* 0 is a put, 1 is a putnext */
  263. {
  264.     int access;             /* create if op 0, write if op 1 */
  265.     DF *dfile;
  266.     uint16 r8tag;           /* RIG and raster tags of image being written */
  267.     char *pal;     /* pointer to palette to be written */
  268.     char newpal[768];  /* Imcomp creates new palette to be associated*/
  269.     int wdim;               /* have dimensions already been written out? */
  270.  
  271.     DFerror = DFE_NOERROR;
  272.  
  273.     if ((xdim<=0) || (ydim<=0)) {
  274.         DFerror = DFE_BADDIM;
  275.         return(-1);
  276.     }
  277.     if (!image) {
  278.         DFerror = DFE_BADPTR;
  279.         return(-1);
  280.     }
  281.     pal = (Newpalette>=0) ? Palette : NULL;
  282.     access = op ? DFACC_WRITE : DFACC_CREATE;
  283.  
  284.     dfile = DFR8Iopen(filename, access);
  285.     if (dfile==NULL) return(-1);
  286.  
  287.     if (!Writeref) Writeref = DFnewref(dfile);
  288.     if (!Writeref) return(-1);
  289.  
  290.     /* write out image */
  291.     if (compress) {
  292.         if (DFputcomp(dfile, DFTAG_CI, Writeref, image, xdim, ydim,
  293.               pal, newpal, compress)<0)
  294.             return(DFIerr(dfile));
  295.         Writerig.image.tag = DFTAG_CI;
  296.         if (compress==DFTAG_IMC) {
  297.             pal = newpal;    /* Imcomp creates new pal */
  298.             Newpalette = 1;    /* write out palette */
  299.         }
  300.     } else {            /* image need not be compressed */
  301.         if (DFputelement(dfile, DFTAG_RI, Writeref, image, xdim*ydim)<0)
  302.             return(DFIerr(dfile));
  303.         Writerig.image.tag = DFTAG_RI;
  304.     }
  305.     Writerig.image.ref = Writeref;
  306.     Writerig.descimage.ncomponents = 1;
  307.     Writerig.aspectratio = 1.0;
  308.  
  309.     /* Write out Raster-8 tags for those who want it */
  310.     r8tag = compress ?
  311.     ((compress==DFTAG_RLE) ? DFTAG_CI8 : DFTAG_II8) : DFTAG_RI8;
  312.     if (DFdup(dfile, r8tag, Writeref, Writerig.image.tag, Writeref)<0)
  313.         return(DFIerr(dfile));
  314.  
  315.     /* Write out palette */
  316.     if (pal) {            /* if there is a palette */
  317.         if (Newpalette==1) {    /* write palette */
  318.             if (DFputelement(dfile, DFTAG_LUT, Writeref, pal, (int32) 768)<0)
  319.                 return(DFIerr(dfile));
  320.             Writerig.lut.tag = DFTAG_LUT;
  321.             Writerig.lut.ref = Writeref;
  322.             Writerig.desclut.xdim = 768;
  323.             Writerig.desclut.ncomponents = 1;
  324.         }
  325.         if (compress!=DFTAG_IMC) Newpalette = 0;
  326.     /* if IMCOMP, original palette not written out */
  327.  
  328.     /* put in Raster-8 stuff also, for those who want it */
  329.         if (DFdup(dfile, DFTAG_IP8, Writeref, Writerig.lut.tag,
  330.           Writerig.lut.ref)<0)
  331.             return(DFIerr(dfile));
  332.     }
  333.  
  334.     /* Write out RIG */
  335.     if ((Writerig.descimage.xdim==xdim) && (Writerig.descimage.ydim==ydim) &&
  336.     (Writerig.descimage.compr.tag==compress))
  337.         wdim = 0;
  338.     else {
  339.         wdim = 1;
  340.         Writerig.descimage.xdim = xdim;
  341.         Writerig.descimage.ydim = ydim;
  342.         Writerig.descimage.compr.tag = compress;
  343.     }
  344.     if (DFR8putrig(dfile, Writeref, &Writerig, wdim)<0) /* writes ID, NT */
  345.         return(DFIerr(dfile));
  346.  
  347.     Lastref = Writeref;        /* remember ref written */
  348.  
  349.     Writeref = 0;               /* don't know ref to write next */
  350.  
  351.     return(DFclose(dfile));
  352. }
  353.  
  354. /*-----------------------------------------------------------------------------
  355.  * Name:    DFR8putimage
  356.  * Purpose: Write RIG to HDF file
  357.  * Inputs:  filename: name of HDF file
  358.  *          image: image to be written to file
  359.  *          xdim, ydim: dimensions of image
  360.  *          compress: compression scheme to be used on image, 0 if none
  361.  * Returns: 0 on success, -1 on failure with DFerror set
  362.  * Users:   HDF HLL users, utilities, other routines
  363.  * Invokes: DFR8Iputimage
  364.  * Remarks: overwrites existing HDF file
  365.  *---------------------------------------------------------------------------*/
  366.  
  367. int DFR8putimage(filename, image, xdim, ydim, compress)
  368. char *filename;
  369. int32 xdim, ydim;
  370. char *image;
  371. int compress;
  372. {
  373.     return(DFR8Iputimage(filename, image, xdim, ydim, compress, 0));
  374. }
  375.  
  376.  
  377. /*-----------------------------------------------------------------------------
  378.  * Name:    DFR8addimage
  379.  * Purpose: Append RIG to HDF file
  380.  * Inputs:  filename: name of HDF file
  381.  *          image: image to be written to file
  382.  *          xdim, ydim: dimensions of image
  383.  *          compress: compression scheme to be used on image, 0 if none
  384.  * Returns: 0 on success, -1 on failure with DFerror set
  385.  * Users:   HDF HLL users, utilities, other routines
  386.  * Invokes: DFR8Iputimage
  387.  * Remarks: inserts image into existing file, will create file if necessary
  388.  *---------------------------------------------------------------------------*/
  389.  
  390. int DFR8addimage(filename, image, xdim, ydim, compress)
  391. char *filename;
  392. int32 xdim, ydim;
  393. char *image;
  394. int compress;
  395. {
  396.     return(DFR8Iputimage(filename, image, xdim, ydim, compress, 1));
  397. }
  398.  
  399.  
  400. /*****************************************************************************/
  401. /* This is the next lower layer - procedures to get and put a RIG. */
  402. /* These are specific to 8-bit */
  403. /*****************************************************************************/
  404.  
  405. /*-----------------------------------------------------------------------------
  406.  * Name:    DFR8getrig
  407.  * Purpose: Read a RIG into memory
  408.  * Inputs:  dfile: pointer to HDF file containing RIG
  409.  *          ref: reference number of RIG to get
  410.  *          rig: struct in which to place info obtained
  411.  * Returns: 0 on success, -1 on failure with DFerror set
  412.  *          contents of RIG in the struct rig
  413.  * Users:   HDF programmers, utilities, DFR8getdims,DFR8getimage
  414.  * Invokes: DFdiget, DFdinext, DFIcheck, DFgetelement
  415.  * Remarks: assumes 8-bit
  416.  *---------------------------------------------------------------------------*/
  417.  
  418. int DFR8getrig(dfile, ref, rig)
  419. DF *dfile;
  420. uint16 ref;
  421. DFRrig *rig;
  422. {
  423.     DFdi elmt;
  424.     char ntstring[4];
  425.  
  426.     DFerror = DFE_NOERROR;
  427.  
  428.     if (DFIcheck(dfile))
  429.         return( -1);
  430.     if (!ref) {
  431.         DFerror = DFE_BADREF;
  432.         return(-1);
  433.     }
  434.  
  435.     if (DFdiread(dfile, DFTAG_RIG, ref)<0) /* read RIG into memory */
  436.         return(-1);
  437.  
  438.     *rig = Zrig;        /* fill rig with zeroes */
  439.     while (!DFdiget(&elmt)) {    /* get next tag/ref from RIG */
  440.         switch (elmt.tag) {    /* process tag/ref */
  441.             case DFTAG_CI:
  442.             case DFTAG_RI:
  443.                 rig->image.tag = elmt.tag; /* put tag/ref in struct */
  444.                 rig->image.ref = elmt.ref;
  445.                 break;
  446.             case DFTAG_LUT:
  447.                 rig->lut.tag = elmt.tag;
  448.                 rig->lut.ref = elmt.ref;
  449.                 break;
  450.             case DFTAG_ID:    /* read description info */
  451. #ifdef DF_STRUCTOK
  452.                 if (DFgetelement(dfile, elmt.tag, elmt.ref, &rig->descimage)<0)
  453.                     return(-1);
  454. #else /*DF_STRUCTOK*/
  455.                 if (DFgetelement(dfile, elmt.tag, elmt.ref, DFtbuf)>0) {
  456.                     register char *p;
  457.                     p = DFtbuf;
  458.                     INT32READ(p, rig->descimage.xdim);
  459.                     INT32READ(p, rig->descimage.ydim);
  460.                     UINT16READ(p, rig->descimage.nt.tag);
  461.                     UINT16READ(p, rig->descimage.nt.ref);
  462.                     INT16READ(p, rig->descimage.ncomponents);
  463.                     INT16READ(p, rig->descimage.interlace);
  464.                     UINT16READ(p, rig->descimage.compr.tag);
  465.                     UINT16READ(p, rig->descimage.compr.ref);
  466.                 } else
  467.                     return(-1);
  468. #endif /*DF_STRUCTOK*/
  469.                 if (rig->descimage.ncomponents!=1) {
  470.                     DFerror = DFE_BADCALL;
  471.                     return(-1);
  472.                 }
  473.                 if (rig->descimage.nt.tag==0) break; /* old RIGs */
  474.  
  475.         /* read NT */
  476.                 if (DFgetelement(dfile, rig->descimage.nt.tag,
  477.                  rig->descimage.nt.ref, ntstring)<0)
  478.                     return(-1);
  479.                 if ((ntstring[2]!=8) || (ntstring[1]!=DFNT_UCHAR)) {
  480.                     DFerror = DFE_BADCALL;
  481.                     return(-1);
  482.                 }
  483.                 break;
  484.             default:        /* ignore unknown tags */
  485.                 break;
  486.         }
  487.     }
  488.     return(0);
  489. }
  490.  
  491. /*-----------------------------------------------------------------------------
  492.  * Name:    DFR8putrig
  493.  * Purpose: Write RIG struct out to HDF file
  494.  * Inputs:  dfile: HDF file pointer
  495.  *          ref: ref to put RIG with
  496.  *          rig: struct containing RIG info to put
  497.  *          wdim: if 1, write out new description records. if 0 already written
  498.  * Returns: 0 on success, -1 on failure with DFerror set
  499.  * Users:   HDF programmers, utilities, DFR8Iputimage, other routines
  500.  * Invokes: DFIcheck, DFdistart, DFdiadd, DFdiend, DFputelement
  501.  * Remarks: assumes 8-bit.  Writes out NT if necessary, ID, ID8 if told to
  502.  *---------------------------------------------------------------------------*/
  503.  
  504. int DFR8putrig(dfile, ref, rig, wdim)
  505. DF *dfile;
  506. uint16 ref;
  507. DFRrig *rig;
  508. int wdim;
  509. {
  510.     static uint16 prevdimref=0; /*ref of previous dimension record, to reuse */
  511.     R8dim im8dim;
  512.     char ntstring[4];
  513.  
  514.     DFerror = DFE_NOERROR;
  515.  
  516.     if (DFIcheck(dfile))
  517.         return( -1);
  518.     if (!ref) {
  519.         DFerror = DFE_BADREF;
  520.         return(-1);
  521.     }
  522.  
  523.     if (!rig->descimage.nt.tag) {
  524.     /* construct and write out NT */
  525.         ntstring[0] = DFNT_VERSION; /* version */
  526.         ntstring[1] = DFNT_UCHAR; /* type */
  527.         ntstring[2] = 8;    /* width: RIG data is 8-bit chars */
  528.         ntstring[3] = DFNTC_BYTE; /* class: data are numeric values */
  529.         if (DFputelement(dfile, DFTAG_NT, ref, ntstring, (int32) 4) <0)
  530.             return(-1);
  531.         rig->descimage.nt.tag = DFTAG_NT;
  532.         rig->descimage.nt.ref = ref;
  533.     }
  534.         
  535.     im8dim.xd = rig->descimage.xdim;
  536.     im8dim.yd = rig->descimage.ydim;
  537.     if (wdim) {
  538. #ifdef DF_STRUCTOK        /* write out description record */
  539.         if (DFputelement(dfile, DFTAG_ID8, ref, &im8dim, (int32) 4)<0) /*ID8 */
  540.             return(-1);
  541.         if (DFputelement(dfile, DFTAG_ID, ref, &rig->descimage,    /* ID */
  542.              sizeof(rig->descimage))<0)
  543.             return(-1);
  544. #else /*DF_STRUCTOK*/
  545.         register char *p;
  546.         p = DFtbuf;
  547.         INT32WRITE(p, rig->descimage.xdim);
  548.         INT32WRITE(p, rig->descimage.ydim);
  549.         UINT16WRITE(p, rig->descimage.nt.tag);
  550.         UINT16WRITE(p, rig->descimage.nt.ref);
  551.         INT16WRITE(p, rig->descimage.ncomponents);
  552.         INT16WRITE(p, rig->descimage.interlace);
  553.         UINT16WRITE(p, rig->descimage.compr.tag);
  554.         UINT16WRITE(p, rig->descimage.compr.ref);
  555.         if (DFputelement(dfile, DFTAG_ID, ref, DFtbuf,(int32)(p-DFtbuf))<0)
  556.             return(-1);
  557.     /* write out ID8 */
  558.         p = DFtbuf;
  559.         UINT16WRITE(p, im8dim.xd);
  560.         UINT16WRITE(p, im8dim.yd);
  561.         if (DFputelement(dfile, DFTAG_ID8, ref, DFtbuf, (int32) 4)<0)
  562.             return(-1);
  563. #endif /*DF_STRUCTOK*/
  564.         prevdimref = ref;
  565.     }
  566.     if (!prevdimref) {
  567.         DFerror = DFE_BADDIM;
  568.         return(-1);
  569.     }
  570.  
  571.     /* prepare to start writing rig */
  572.     /* ### NOTE: the second parameter to this call may go away */
  573.     if (DFdisetup(10)<0) return(-1); /* max 10 tag/refs in set */
  574.  
  575.     /* add tag/ref to RIG - image description, image and palette */
  576.     if (DFdiput(DFTAG_ID, prevdimref) < 0) return(-1);
  577.  
  578.     if (DFdiput(rig->image.tag, rig->image.ref) < 0) return(-1);
  579.  
  580.     if (rig->lut.ref)
  581.         if (DFdiput(rig->lut.tag, rig->lut.ref) < 0) return(-1);
  582.  
  583.         /* write out RIG */
  584.     return(DFdiwrite(dfile, DFTAG_RIG, ref));
  585. }
  586.  
  587.  
  588. /*-----------------------------------------------------------------------------
  589.  * Name:    DFR8nimages
  590.  * Purpose: How many images are present in this file?
  591.  * Inputs:  filename: name of HDF file
  592.  * Returns: number of images  on success, -1 on failure with DFerror set
  593.  * Users:   HDF programmers, other routines and utilities
  594.  * Invokes: DFR8Iopen, DFclose, DFnumber
  595.  * Remarks: the number is the number of RIGs if RIGs are present
  596.  *          If not, it is the number of RI8s + number of CI8s
  597.  *---------------------------------------------------------------------------*/
  598.  
  599. int DFR8nimages(filename)
  600. char *filename;
  601. {
  602.     DF *dfile;
  603.     int nimages=0;
  604.  
  605.     DFerror = DFE_NOERROR;
  606.  
  607.     /* should use reopen if same file as last time - more efficient */
  608.     dfile = DFR8Iopen(filename, DFACC_READ);
  609.     if (dfile==NULL) return(-1);
  610.  
  611.     /* find next rig */
  612.     if (foundRig) {        /* either RIGs present or don't know */
  613.         nimages = DFnumber(dfile, DFTAG_RIG); /* count number of RIGs */
  614.         if (nimages>0) {
  615.             foundRig = 1;
  616.             if (DFclose(dfile)<0) return(-1);
  617.             return(nimages);
  618.         }
  619.         foundRig = 0;
  620.     }
  621.     nimages = DFnumber(dfile, DFTAG_RI8);
  622.     nimages += DFnumber(dfile, DFTAG_CI8);
  623.     if (DFclose(dfile)<0) return(-1);
  624.     return(nimages);
  625. }
  626.  
  627. /*-----------------------------------------------------------------------------
  628.  * Name:    DFR8readref
  629.  * Purpose: Set ref of image to get next
  630.  * Inputs:  filename: file to which this applies
  631.  *          ref: reference number of next get
  632.  * Returns: 0 on success, -1 on failure
  633.  * Users:   HDF programmers, other routines and utilities
  634.  * Invokes: DFR8Iopen, DFIfind
  635.  * Remarks: checks if image with this ref exists
  636.  *---------------------------------------------------------------------------*/
  637.  
  638. int DFR8readref(filename, ref)
  639. char *filename;
  640. uint16 ref;
  641. {
  642.     DF *dfile;
  643.     int cdd;
  644.     DFdle *dlep;
  645.  
  646.     DFerror = DFE_NOERROR;
  647.  
  648.     dfile = DFR8Iopen(filename, DFACC_READ);
  649.     if (dfile==NULL) return(-1);
  650.     if (DFIfind(dfile, DFTAG_RIG, ref, 1, 0, 0, &dlep, &cdd)<0)
  651.         if (DFIfind(dfile, DFTAG_RI8, ref, 1, 0, 0, &dlep, &cdd)<0)
  652.             if (DFIfind(dfile, DFTAG_CI8, ref, 1, 0, 0, &dlep, &cdd)<0)
  653.                 return(DFIerr(dfile));
  654.     Refset = ref;
  655.     Newdata = 0;
  656.     return(DFclose(dfile));
  657. }
  658.  
  659. /*-----------------------------------------------------------------------------
  660.  * Name:    DFR8writeref
  661.  * Purpose: Set ref of image to put next
  662.  * Inputs:  filename: file to which this applies
  663.  *          ref: reference number of next put
  664.  * Returns: 0 on success, -1 on failure
  665.  * Users:   HDF programmers, other routines and utilities
  666.  * Invokes: DFR8Iopen, DFIfind
  667.  * Remarks: none
  668.  *---------------------------------------------------------------------------*/
  669.  
  670. /* shut lint up */
  671. /* ARGSUSED */
  672. int DFR8writeref(filename, ref)
  673. char *filename;
  674. uint16 ref;
  675. {
  676.     DFerror = DFE_NOERROR;
  677.  
  678.     Writeref = ref;
  679.     return(0);
  680. }
  681.  
  682. static char Lastfile[DF_MAXFNLEN];          /* last file opened */
  683.  
  684. /*-----------------------------------------------------------------------------
  685.  * Name:    DFR8restart
  686.  * Purpose: Do not remember info about file - get again from first image
  687.  * Inputs:  none
  688.  * Returns: 0 on success
  689.  * Users:   HDF programmers
  690.  * Remarks: Just reset Lastfile to NULL
  691.  *---------------------------------------------------------------------------*/
  692.  
  693. int DFR8restart()
  694. {
  695.     Lastfile[0] = '\0';
  696.     return(0);
  697. }
  698.  
  699.  
  700. /*-----------------------------------------------------------------------------
  701.  * Name:    DFR8lastref
  702.  * Purpose: Return last ref written or read
  703.  * Inputs:  none
  704.  * Globals: Lastref
  705.  * Returns: ref on success, -1 on error with DFerror set
  706.  * Users:   HDF users, utilities, other routines
  707.  * Invokes: none
  708.  * Method:  return Lastref
  709.  * Remarks: none
  710.  *---------------------------------------------------------------------------*/
  711.  
  712. int DFR8lastref()
  713. {
  714.     return((int) Lastref);
  715. }
  716.  
  717.  
  718.  
  719. /******************************************************************************/
  720. /*----------------------- Internal routines ---------------------------------*/
  721. /******************************************************************************/
  722.  
  723.  
  724. /*-----------------------------------------------------------------------------
  725.  * Name:    DFR8Iopen
  726.  * Purpose: open or reopen a file
  727.  * Inputs:  filename: name of file to open
  728.  *          access : access mode
  729.  * Returns: file pointer on success, NULL on failure with DFerror set
  730.  * Users:   HDF systems programmers, all the RIG routines 
  731.  * Invokes: DFopen
  732.  * Remarks: This is a hook for someday providing more efficient ways to
  733.  *          reopen a file, to avoid re-reading all the headers
  734.  *---------------------------------------------------------------------------*/
  735.  
  736. DF *DFR8Iopen(filename, access)
  737. char *filename;
  738. int access;
  739. {
  740.  
  741.     DF *dfile;
  742.  
  743.     /* use reopen if same file as last time - more efficient */
  744.     if (strncmp(Lastfile,filename,DF_MAXFNLEN) || (access==DFACC_CREATE)) {
  745.                 /* treat create as different file */
  746.         if (!(dfile = DFopen(filename, access, -1))) return(NULL);
  747.         foundRig = -1;        /* don't know if any RIGs in file */
  748.         Refset = 0;        /* no ref to get set for this file */
  749.         Newdata = 0;
  750.         Readrig = Zrig;        /* blank out read/write RIGs */
  751.         Writerig = Zrig;
  752.         if (Newpalette!=(-1)) Newpalette = 1; /* need to write out palette */
  753.     } else
  754.         if (!(dfile = DFopen(filename, access, -1))) return(NULL);
  755.  
  756.     strncpy(Lastfile, filename, DF_MAXFNLEN);
  757.     /* remember filename, so reopen may be used next time if same file */
  758.     return(dfile);
  759. }
  760.  
  761. /*-----------------------------------------------------------------------------
  762.  * Name:    DFR8Iriginfo
  763.  * Purpose: Getinformation about next RIG or Raster-8 in file
  764.  * Inputs:  dfile: pointer to DF file
  765.  * Returns: 0 on success, -1 on failure with DFerror set
  766.  * Users:   HDF systems programmers
  767.  * Invokes: DFIfind, DFgetelement
  768.  * Remarks: checks for RIGs first, then RI8s
  769.  *          if Refset set, gets image with that ref, if any
  770.  *---------------------------------------------------------------------------*/
  771.  
  772. int DFR8Iriginfo(dfile)
  773. DF *dfile;
  774. {
  775.     DFdle *dlep;
  776.     int cdd;
  777.     uint16 riref=0, ciref=0;
  778.  
  779. #ifdef DF_STRUCTOK
  780.     R8dim im8dim;
  781. #endif /*DF_STRUCTOK*/
  782.  
  783.     /* find next rig */
  784.     if (foundRig) {        /* either RIGs present or don't know */
  785.     do {
  786.         DFerror = DFE_NOERROR;
  787.         if (Refset &&
  788.         DFIfind(dfile, DFTAG_RIG, Refset, 1,0,0, &dlep, &cdd)<0) {
  789.         /* try for RI8 and CI8s */
  790.         }
  791.             /* in next line, !ref is passed for isfirst.  If we have found
  792.            a ref before, ref is non-zero, hence isfirst is 0.  If
  793.            we have not found anything yet, ref is 0 and isfirst is 1 */
  794.         else if (!Refset && DFIfind(dfile, DFTAG_RIG, DFREF_WILDCARD,
  795.                     !Readrig.image.ref, Readrig.image.tag,
  796.                                         Readrig.image.ref, &dlep, &cdd) <0) {
  797.         if (foundRig==1) { /* RIGs present, but no more to return */
  798.             DFerror = DFE_NOMATCH;
  799.             return(-1);
  800.         }
  801.         foundRig = 0;    /* No RIGs present in file */
  802.         }
  803.         else {        /* RIG found */
  804.         if (DFR8getrig(dfile, dlep->dd[cdd].ref, &Readrig)<0) {
  805.             if (Refset || (DFerror != DFE_BADCALL)) {
  806.             Refset = 0;
  807.             return(-1);
  808.             }
  809.             Readrig.image.ref = dlep->dd[cdd].ref; /*to get next one */
  810.         } else { foundRig = 1; Refset = 0; }
  811.         }
  812.     } while (DFerror==DFE_BADCALL);
  813.     }
  814.     if (Refset || !foundRig) {    /* No RIGs present, look for RI8 and CI8 */
  815.     /* look for Refset if DFR8ref called, else look for next ref */
  816.         if ((Refset &&
  817.          (DFIfind(dfile, DFTAG_RI8, Refset, 1, 0, 0, &dlep, &cdd)==0)) ||
  818.         (!Refset &&
  819.          (DFIfind(dfile, DFTAG_RI8, DFREF_WILDCARD, !Readrig.image.ref,
  820.               Readrig.image.tag, Readrig.image.ref, &dlep, &cdd)==0)))
  821.             riref = dlep->dd[cdd].ref;
  822.  
  823.         if ((Refset &&
  824.          (DFIfind(dfile, DFTAG_CI8, Refset, 1, 0, 0, &dlep, &cdd)==0)) ||
  825.         (!Refset &&
  826.          (DFIfind(dfile, DFTAG_CI8, DFREF_WILDCARD, !Readrig.image.ref,
  827.               Readrig.image.tag, Readrig.image.ref, &dlep, &cdd)==0)))
  828.             ciref = dlep->dd[cdd].ref;
  829.  
  830.         Refset = 0;
  831.         if (!riref && !ciref) {
  832.             DFerror = DFE_NOMATCH;
  833.             return(-1);
  834.         }
  835.         if ((!ciref) || (riref && (riref<ciref))) { /* next image is RI8 */
  836.             Readrig.image.ref = riref;
  837.             Readrig.image.tag = DFTAG_RI8;
  838.         }
  839.         else {            /* next image is CI8 */
  840.             Readrig.image.ref = ciref;
  841.             Readrig.image.tag = DFTAG_CI8;
  842.             Readrig.descimage.compr.tag = DFTAG_RLE;
  843.         }
  844.  
  845. #ifdef DF_STRUCTOK        /* read in dimensions */
  846.         if (DFgetelement(dfile, DFTAG_ID8, Readrig.image.ref, &im8dim)>=0) {
  847.             Readrig.descimage.xdim = im8dim.xd;
  848.             Readrig.descimage.ydim = im8dim.yd;
  849.         }
  850. #else /*DF_STRUCTOK*/
  851.         if (DFgetelement(dfile, DFTAG_ID8, Readrig.image.ref, DFtbuf)>=0) {
  852.             register char *p;
  853.             p = DFtbuf;
  854.             UINT16READ(p, Readrig.descimage.xdim);
  855.             UINT16READ(p, Readrig.descimage.ydim);
  856.         }
  857. #endif /*DF_STRUCTOK*/
  858.         else return(-1);
  859.  
  860.         if (DFIfind(dfile, DFTAG_IP8, Readrig.image.ref, 1, 0, 0, &dlep,
  861.             &cdd)==0) {
  862.             Readrig.lut.tag = DFTAG_IP8;
  863.             Readrig.lut.ref = Readrig.image.ref;
  864.         }
  865.     }
  866.     Lastref = Readrig.image.ref; /* remember ref read */
  867.     return(0);
  868. }
  869.